/*
 * @Author: dumin 173672326@qq.com
 * @Date: 2023-12-05 17:59:58
 * @LastEditors: dumin 173672326@qq.com
 * @LastEditTime: 2023-12-08 16:37:04
 * @Description: 使用 ResizeObserver ，针对宽度改变后进行回调函数进行优化
 */

// 创建 dom 与 回调函数的对应关系，【映射关系】，防止内存泄漏（Map），建立弱映射关系，使用 WeakMap
const map = new WeakMap();

const ob = new ResizeObserver(entries => {
  entries.forEach(entry => {
    // 运行 entery.target 对应的回调函数
    const handler = map.get(entry.target)

    if (handler) {
      handler({ boxMsg: entry })
    }
  })
})

// 防抖函数
function debounce(fn, delay) {
  let timer
  return function(...args) {
    timer && clearTimeout(timer)

    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

export default {
  mounted(el, binding, vnode) {
    // 是否开启防抖
    if(vnode.props?.debounce) {
      if(typeof vnode.props.debounce !== 'number') { 
        console.warn('防抖属性 debounce 须为数字')
      }
      // 防抖
      binding.value = debounce(binding.value, typeof vnode.props.debounce === 'number' ? vnode.props.debounce : 300)
    }
    // 记录 el 对应的回调函数
    map.set(el, binding.value)

    // 监听 el 元素的尺寸变化
    ob.observe(el)
  },

  unmounted(el) {
    // 取消监听
    ob.unobserve(el)

    // 移除 el 对应的回调函数
    map.delete(el)
  }
}
